package com.lianjia.analysis.service.impl;

import com.lianjia.analysis.model.HouseInfo;
import com.lianjia.analysis.model.dto.PageDTO;
import com.lianjia.analysis.repository.HouseInfoRepository;
import com.lianjia.analysis.service.HouseService;
import com.lianjia.analysis.service.cache.CacheService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class HouseServiceImpl implements HouseService {

    @Autowired
    private HouseInfoRepository houseInfoRepository;
    
    @Autowired
    private MongoTemplate mongoTemplate;
    
    @Autowired
    private CacheService cacheService;

    @Override
    public List<String> getAllCities() {
        String cacheKey = "house:cities";
        List<String> cities = cacheService.get(cacheKey);
        if (cities == null) {
            cities = houseInfoRepository.findDistinctCities();
            if (cities == null || cities.isEmpty()) {
                // 备选方案：如果聚合查询未能返回结果，则尝试使用原来的方式
                List<HouseInfo> houseInfos = houseInfoRepository.findAllCityNames();
                cities = houseInfos.stream()
                        .map(HouseInfo::getCityName)
                        .filter(Objects::nonNull)
                        .distinct()
                        .collect(Collectors.toList());
            }
            cacheService.set(cacheKey, cities, 3600);
        }
        return cities;
    }

    @Override
    public Map<String, List<String>> getAllDistricts() {
        String cacheKey = "house:districts";
        Map<String, List<String>> districts = cacheService.get(cacheKey);
        if (districts == null) {
            districts = new HashMap<>();
            List<String> cities = getAllCities();
            for (String city : cities) {
                List<HouseInfo> houseInfos = houseInfoRepository.findByCityName(city);
                List<String> cityDistricts = houseInfos.stream()
                        .map(HouseInfo::getDistrict)
                        .filter(Objects::nonNull)
                        .distinct()
                        .collect(Collectors.toList());
                districts.put(city, cityDistricts);
            }
            cacheService.set(cacheKey, districts, 3600);
        }
        return districts;
    }

    @Override
    public List<String> getPriceRanges() {
        return Arrays.asList(
                "0-50万", "50-100万", "100-150万", "150-200万", 
                "200-300万", "300-500万", "500-1000万", "1000万以上"
        );
    }

    @Override
    public List<String> getAreaRanges() {
        return Arrays.asList(
                "50㎡以下", "50-70㎡", "70-90㎡", "90-110㎡", 
                "110-130㎡", "130-150㎡", "150-200㎡", "200㎡以上"
        );
    }

    @Override
    public List<String> getLayouts() {
        String cacheKey = "house:layouts";
        List<String> layouts = cacheService.get(cacheKey);
        if (layouts == null) {
            layouts = mongoTemplate.findDistinct("details.configuration", HouseInfo.class, String.class)
                    .stream()
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            cacheService.set(cacheKey, layouts, 3600);
        }
        return layouts;
    }

    @Override
    public List<String> getDecorations() {
        String cacheKey = "house:decorations";
        List<String> decorations = cacheService.get(cacheKey);
        if (decorations == null) {
            decorations = mongoTemplate.findDistinct("details.decorate", HouseInfo.class, String.class)
                    .stream()
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            cacheService.set(cacheKey, decorations, 3600);
        }
        return decorations;
    }

    @Override
    public PageDTO<HouseInfo> findHouses(String city, String district, String priceRange, 
                                        String areaRange, String layout, String decoration, 
                                        int page, int size) {
        return findHouses(city, priceRange, areaRange, layout, decoration, null, "default", page, size);
    }
    
    /**
     * 增强版查询方法，支持更多参数和排序
     */
    public PageDTO<HouseInfo> findHouses(String city, String priceRange, String areaRange,
                                       String layout, String decoration, String query,
                                       String sort, int page, int size) {
        // 构建查询条件
        Query query1 = new Query();
        
        // 记录查询条件，方便调试
        List<String> conditions = new ArrayList<>();
        
        // 添加筛选条件
        if (city != null && !city.isEmpty()) {
            query1.addCriteria(Criteria.where("cityName").is(city));
            conditions.add("城市: " + city);
        }
        
        // 处理价格区间
        if (priceRange != null && !priceRange.isEmpty()) {
            double[] range = parseRange(priceRange);
            if (range != null) {
                if (range[1] == Double.MAX_VALUE) {
                    // 只有下限
                    query1.addCriteria(Criteria.where("price.totalPrice").gte(range[0]));
                    conditions.add("价格 >= " + range[0] + "万");
                } else if (range[0] == 0) {
                    // 只有上限
                    query1.addCriteria(Criteria.where("price.totalPrice").lt(range[1]));
                    conditions.add("价格 < " + range[1] + "万");
                } else {
                    // 上下限都有
                    query1.addCriteria(Criteria.where("price.totalPrice").gte(range[0]).lt(range[1]));
                    conditions.add("价格: " + range[0] + "-" + range[1] + "万");
                }
            }
        }
        
        // 处理面积区间
        if (areaRange != null && !areaRange.isEmpty()) {
            double[] range = parseRange(areaRange);
            if (range != null) {
                if (range[1] == Double.MAX_VALUE) {
                    // 只有下限
                    query1.addCriteria(Criteria.where("details.areaValue").gte(range[0]));
                    conditions.add("面积 >= " + range[0] + "㎡");
                } else if (range[0] == 0) {
                    // 只有上限
                    query1.addCriteria(Criteria.where("details.areaValue").lt(range[1]));
                    conditions.add("面积 < " + range[1] + "㎡");
                } else {
                    // 上下限都有
                    query1.addCriteria(Criteria.where("details.areaValue").gte(range[0]).lt(range[1]));
                    conditions.add("面积: " + range[0] + "-" + range[1] + "㎡");
                }
            }
        }
        
        // 处理户型 - 根据数据库结构修正
        if (layout != null && !layout.isEmpty()) {
            // 户型存储在details.configuration字段中
            // 更宽松的匹配方式，移除正则表达式前后的.*，使用更精准的匹配
            System.out.println("搜索户型: " + layout);
            query1.addCriteria(Criteria.where("details.configuration").regex(layout, "i"));
            conditions.add("户型: " + layout);
            
            // 添加详细日志
            System.out.println("户型搜索条件: 字段='details.configuration', 值='" + layout + "', 使用正则匹配(不区分大小写)");
        }
        
        // 处理装修 - 根据数据库结构修正
        if (decoration != null && !decoration.isEmpty()) {
            // 装修存储在details.decorate字段中
            query1.addCriteria(Criteria.where("details.decorate").regex(".*" + decoration + ".*", "i"));
            conditions.add("装修: " + decoration);
        }
        
        // 处理关键词查询
        if (query != null && !query.isEmpty()) {
            // 创建一个OR条件，在多个字段中搜索
            Criteria keywordCriteria = new Criteria();
            keywordCriteria.orOperator(
                Criteria.where("title").regex(".*" + query + ".*", "i"),
                Criteria.where("location").regex(".*" + query + ".*", "i")
            );
            query1.addCriteria(keywordCriteria);
            conditions.add("关键词: " + query);
        }
        
        // 打印查询条件，帮助调试
        System.out.println("查询条件: " + String.join(", ", conditions));
        
        // 计算总数
        long total = mongoTemplate.count(query1, HouseInfo.class);
        System.out.println("匹配结果总数: " + total);
        
        // 添加排序
        if (sort != null && !sort.equals("default")) {
            switch (sort) {
                case "priceAsc":
                    query1.with(Sort.by(Sort.Direction.ASC, "price.totalPrice"));
                    break;
                case "priceDesc":
                    query1.with(Sort.by(Sort.Direction.DESC, "price.totalPrice"));
                    break;
                case "areaAsc":
                    query1.with(Sort.by(Sort.Direction.ASC, "details.areaValue"));
                    break;
                case "areaDesc":
                    query1.with(Sort.by(Sort.Direction.DESC, "details.areaValue"));
                    break;
                default:
                    // 默认按创建时间倒序
                    query1.with(Sort.by(Sort.Direction.DESC, "createTime"));
                    break;
            }
        } else {
            // 默认按创建时间倒序
            query1.with(Sort.by(Sort.Direction.DESC, "createTime"));
        }
        
        // 添加分页
        // 修复分页参数，确保page从0开始
        int pageIndex = page;
        if (pageIndex > 0) {
            pageIndex = pageIndex - 1;
        }
        query1.skip((long) pageIndex * size).limit(size);
        
        // 执行查询
        List<HouseInfo> houses = mongoTemplate.find(query1, HouseInfo.class);
        System.out.println("返回结果数: " + houses.size());
        
        // 构建分页结果
        PageDTO<HouseInfo> pageDTO = new PageDTO<>();
        pageDTO.setContent(houses);
        pageDTO.setTotalElements(total);
        pageDTO.setTotalPages((int) Math.ceil((double) total / size));
        pageDTO.setNumber(page);
        pageDTO.setSize(size);
        pageDTO.setFirst(page == 0 || page == 1);
        pageDTO.setLast(page >= (int) Math.ceil((double) total / size) - 1);
        
        return pageDTO;
    }

    @Override
    public HouseInfo findHouseById(String id) {
        Optional<HouseInfo> houseInfo = houseInfoRepository.findById(id);
        return houseInfo.orElse(null);
    }

    @Override
    public List<HouseInfo> findSimilarHouses(String id) {
        // 获取当前房源
        HouseInfo house = findHouseById(id);
        if (house == null) {
            return Collections.emptyList();
        }
        
        // 构建查询条件：相同城市、区域、相近价格和面积
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").ne(id)); // 排除当前房源
        query.addCriteria(Criteria.where("cityName").is(house.getCityName()));
        query.addCriteria(Criteria.where("district").is(house.getDistrict()));
        
        // 价格范围：上下浮动20%
        if (house.getPrice() != null && house.getPrice().getTotalPrice() != null) {
            double totalPrice = house.getPrice().getTotalPrice();
            double minPrice = totalPrice * 0.8;
            double maxPrice = totalPrice * 1.2;
            query.addCriteria(Criteria.where("price.totalPrice").gte(minPrice).lte(maxPrice));
        }
        
        // 面积范围：上下浮动20%
        Double areaValue = house.getAreaValue();
        if (areaValue != null) {
            double minArea = areaValue * 0.8;
            double maxArea = areaValue * 1.2;
            query.addCriteria(Criteria.where("details.areaValue").gte(minArea).lte(maxArea));
        }
        
        // 限制返回10条
        query.limit(10);
        
        return mongoTemplate.find(query, HouseInfo.class);
    }
    
    /**
     * 解析区间字符串，如"50-100万"、"90-110㎡"
     * @param rangeStr 区间字符串
     * @return 区间数组，[最小值, 最大值]
     */
    private double[] parseRange(String rangeStr) {
        if (rangeStr == null || rangeStr.trim().isEmpty()) {
            return null;
        }
        
        try {
            rangeStr = rangeStr.trim();
            
            // 处理"xx以下"
            if (rangeStr.endsWith("以下")) {
                String numStr = rangeStr.substring(0, rangeStr.indexOf("以下")).trim();
                numStr = cleanNumberString(numStr);
                double max = Double.parseDouble(numStr);
                return new double[]{0, max};
            }
            
            // 处理"xx以上"
            if (rangeStr.endsWith("以上")) {
                String numStr = rangeStr.substring(0, rangeStr.indexOf("以上")).trim();
                numStr = cleanNumberString(numStr);
                double min = Double.parseDouble(numStr);
                return new double[]{min, Double.MAX_VALUE};
            }
            
            // 处理"xx-xx"
            if (rangeStr.contains("-")) {
                String[] parts = rangeStr.split("-");
                if (parts.length == 2) {
                    String minStr = cleanNumberString(parts[0].trim());
                    String maxStr = cleanNumberString(parts[1].trim());
                    
                    double min = minStr.isEmpty() ? 0 : Double.parseDouble(minStr);
                    double max = maxStr.isEmpty() ? Double.MAX_VALUE : Double.parseDouble(maxStr);
                    
                    return new double[]{min, max};
                }
            }
        } catch (Exception e) {
            // 解析失败，记录日志
            System.out.println("解析区间字符串失败: " + rangeStr + ", 错误: " + e.getMessage());
        }
        
        return null;
    }
    
    /**
     * 清理数字字符串，去除单位和其他非数字字符
     */
    private String cleanNumberString(String str) {
        if (str == null) return "";
        
        // 去除常见单位和非数字字符
        return str.replaceAll("[^0-9.]", "");
    }
} 